#pragma once

#include <string>
#include <mutex>
#include <memory>
#include "awi_dfu.h"

namespace DeviceUpgradeNameSpace{
#define BIN_STEP 4096
#define AWI_DFU_PRO_RESET_REQ_CODE 0x0001
#define AWI_DFU_PRO_RESET_REP_CODE 0x0081
#define AWI_DFU_PRO_DEVICE_INFO_REQ_CODE  0x0002
#define AWI_DFU_PRO_DEVICE_INFO_REP_CODE  0x0082
#define AWI_DFU_PRO_UPGRADE_START_REQ_CODE 0x0003
#define AWI_DFU_PRO_UPGRADE_START_REP_CODE 0x0083
#define AWI_DFU_PRO_UPGRADE_STOP_REQ_CODE 0x0004
#define AWI_DFU_PRO_UPGRADE_STOP_REP_CODE 0x0084
#define AWI_DFU_PRO_UPGRADE_BIN_START_REQ_CODE 0x0005
#define AWI_DFU_PRO_UPGRADE_BIN_START_REP_CODE 0x0085
#define AWI_DFU_PRO_UPGRADE_BIN_REQ_CODE 0x0006
#define AWI_DFU_PRO_UPGRADE_BIN_REP_CODE 0x0086
#define AWI_DFU_PRO_UPGRADE_VIDEO_BIN_REQ_CODE 0x0011
#define AWI_DFU_PRO_UPGRADE_VIDEO_BIN_REP_CODE 0x0091
#define AWI_DFU_PRO_UPGRADE_VIDEO_BIN_SLICE_REQ_CODE 0x0012
#define AWI_DFU_PRO_UPGRADE_VIDEO_BIN_SLICE_REP_CODE 0x0092
#define AWI_DFU_PRO_UNKNOW_CODE 0xFFFF

#define BUFFER_SIZE 1024
typedef struct {
    awi_dfu_t *dfu;
    int dev_count;
    char* tinf_file;
	char* tips_file;
	char* finf_file;
	char* firm_file;
    char* ats_file;
    char* rk_file;
    char* video_file;
    uint32_t flash_block;
    uint32_t slice_size;
    uint32_t slices_total;
    uint32_t cur_slice_index;
    uint32_t bin_size;
    uint16_t dst;
    bool ready[5];
    FILE *fp;
    uint8_t bin_index;
    int step;
    bool downing;
    bool error;
    bool success;

    int deice_fd;
}dfu_proc_t;
}

enum UpgradeType{
    A20SERIES,
    A15SERIES,
    VIDEOSERIES
};



//这个类主要用于不同类型设备的升级管理，需要兼容所有设备的升级
class DeviceUpgradeUtil : public std::enable_shared_from_this<DeviceUpgradeUtil>{

    public:
        DeviceUpgradeUtil(UpgradeType type);
        DeviceUpgradeUtil(){}
        ~DeviceUpgradeUtil(){}
        bool Upgrade(std::string devFilePath, const std::string& upgradeFilePath);

        bool IsUpgrading();
        int GetUpgradeProgress();
        bool setDigitalTotal(int total);
    private:
        bool A15Upgrade();
        bool A20Upgrade();
        bool VideoUpgrade();
        void dfuProcProcess();
        void dfuVideoProcProcess();
        void deviceUpgradeRecv(uint16_t ctrl, uint16_t dst, uint16_t src, uint16_t version, const uint8_t *payload, int bytes);
        void deviceVideoUpgradeRecv(uint16_t ctrl, uint16_t dst, uint16_t src, uint16_t version, const uint8_t *payload, int bytes);
        void upgradeSend(const uint8_t *data, int bytes);
       
    private:
        //这个成员变量用于保存升级所需要的dfu结构体，由于各类设备升级机制不一样，结构体也不一样所以这里需要声明多个结构体提供给各类设备使用
        DeviceUpgradeNameSpace::dfu_proc_t m_upgrade_dfu; //适用于A15升级所需要的dfu结构体
        //级联设备需要设置准确的级联设备个数
        

        //用于存储设备节点路径
        std::string m_device_file_path;
        //升级文件的路径
        std::string m_upgrade_file_path;
        int         m_packetCount;
        //升级的类型
        UpgradeType m_upgrade_type;

        //级联设备的个数
        int m_digitaiTatal = 1;

        //这两个变量用于保存计算升级进度所需要的变量    
        long long m_current_upgrade_size;
        long long m_total_upgrade_size;
        bool m_isUpgrading = false;
};